home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / vmsg.c_ / vmsg.bin
Encoding:
Text File  |  1993-11-19  |  23.3 KB  |  710 lines

  1. /****************************************************************************
  2.  *
  3.  *   vmsg.c
  4.  * 
  5.  *   Video Message Processing
  6.  *
  7.  *   Microsoft Video for Windows Sample Capture Driver
  8.  *   Chips & Technologies 9001 based frame grabbers.
  9.  *
  10.  ***************************************************************************/
  11. /**************************************************************************
  12.  *
  13.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  14.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  15.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  16.  *  PURPOSE.
  17.  *
  18.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  19.  * 
  20.  **************************************************************************/
  21.  
  22. #include <windows.h>
  23. #include <mmsystem.h>
  24. #include <msvideo.h>
  25. #include <msviddrv.h>
  26. #include "ct.h"
  27. #include "config.h"
  28. #include "debug.h"
  29.  
  30. #define WIDTHBYTES(i)     ((unsigned)((i+31)&(~31))/8)  /* ULONG aligned ! */
  31.  
  32. static BOOL             fDeviceInitialized = FALSE;
  33. extern LPVIDEOHDR    lpVHdrFirst;
  34.  
  35. PCHANNEL NEAR PASCAL VideoOpen( LPVIDEO_OPEN_PARMS lpOpenParms)
  36. {
  37.     PCHANNEL    pChannel;
  38.     DEVICE_INIT di;
  39.     LPDWORD lpdwError = &lpOpenParms->dwError;
  40.     DWORD dwFlags = lpOpenParms-> dwFlags;
  41.  
  42.     //
  43.     //  if this is the very first open then init the hardware.
  44.     //
  45.  
  46.     *lpdwError = DV_ERR_OK;
  47.  
  48.     /* Only initalize on first call... */
  49.     if (!fDeviceInitialized) {
  50.  
  51.         /* Get Port/IRQ/Base, etc. from ini file */
  52.         GetHardwareSettingsFromINI (&di);
  53.  
  54. #if DEBUG
  55.         {
  56.             char buf[80];
  57.             wsprintf (buf, "Trying BasePort=%X,   IRQ=%d,   BaseMemory=%X", 
  58.                     di.wIOBase, di.bInterrupt, di.wSegment);
  59.             D1(buf);
  60.         }
  61. #endif
  62.         // Perform hardware initialization
  63.         if (! HardwareInit (&di)) {
  64.             *lpdwError = DV_ERR_NOTDETECTED;
  65.             return NULL;
  66.         }
  67.  
  68.         ConfigGetSettings();   // Get global hue, sat, channel, zoom
  69.  
  70.         // Create selector(s) to memory
  71.         GetFrameBufferPointer ((BYTE) (di.wSegment));
  72.  
  73.         // Can we access the frame buffer?
  74.     if ((*lpdwError = InitCheckMem()) == DV_ERR_OK) {  
  75.             if (ConfigInit(&di)) {       // Allocate copy buffer, init globals
  76.                 if (TransInit ()) {      // Init XLateTBLs, (ret. 0 on success)
  77.                     *lpdwError = DV_ERR_NOMEM;
  78.                 }
  79.                 else
  80.                     fDeviceInitialized = TRUE;
  81.             }
  82.             else
  83.                 *lpdwError = DV_ERR_NOMEM;
  84.     }
  85.  
  86.         if (*lpdwError != DV_ERR_OK) {
  87.             TransFini ();           // Free the translation table
  88.         HardwareFini();
  89.         return NULL;
  90.         }
  91. #if DEBUG
  92.         {
  93.             char buf[80];
  94.             wsprintf (buf, "Actual BasePort=%X,   IRQ=%d,   BaseMemory=%X", 
  95.                     wPCVideoAddress, gbInt, di.wSegment);
  96.             D1(buf);
  97.         }
  98. #endif
  99.     } // end if this is the first open
  100.  
  101.     // get instance memory
  102.     pChannel = (PCHANNEL)LocalAlloc (LPTR, sizeof(CHANNEL));
  103.  
  104.     if (pChannel == NULL)
  105.         return (PCHANNEL) NULL;
  106.  
  107.     //
  108.     //  make sure the channel is not already in use
  109.     //
  110.     switch ( dwFlags & 
  111.         ( VIDEO_EXTERNALIN | VIDEO_EXTERNALOUT | VIDEO_IN | VIDEO_OUT) ) {
  112.  
  113.         case VIDEO_EXTERNALIN:
  114.             if( gwCaptureUsage >= MAX_CAPTURE_CHANNELS)
  115.                 goto error;
  116.             gwCaptureUsage++;
  117.             break;
  118.  
  119.         case VIDEO_EXTERNALOUT:
  120.             if( gwDisplayUsage >= MAX_DISPLAY_CHANNELS)
  121.                 goto error;
  122.             gwDisplayUsage++;
  123.             break;
  124.  
  125.         case VIDEO_IN:
  126.             if( gwVideoInUsage >= MAX_IN_CHANNELS)
  127.                 goto error;
  128.             gwVideoInUsage++;
  129.             break;
  130.  
  131.         case VIDEO_OUT:
  132.             if( gwVideoOutUsage >= MAX_OUT_CHANNELS)
  133.                 goto error;
  134.             gwVideoOutUsage++;
  135.             break;
  136.  
  137.         default:
  138.             goto error;
  139.     }
  140.  
  141.     //
  142.     //  now that the hardware is allocated init our instance struct.
  143.     //
  144.     pChannel->fccType           = OPEN_TYPE_VCAP;
  145.     pChannel->dwOpenType        = 
  146.     (dwFlags & (VIDEO_EXTERNALIN|VIDEO_EXTERNALOUT|VIDEO_IN|VIDEO_OUT));
  147.     pChannel->dwOpenFlags       = dwFlags;
  148.     pChannel->lpVHdr            = NULL;
  149.     pChannel->dwError           = 0L;
  150.  
  151.     gwDriverUsage++;
  152.     return pChannel;
  153.  
  154. error:
  155.     if (pChannel)
  156.         LocalFree((HLOCAL)pChannel);
  157.  
  158.     *lpdwError = DV_ERR_ALLOCATED;
  159.  
  160.     return NULL;
  161. }
  162.  
  163. DWORD NEAR PASCAL VideoClose(PCHANNEL pChannel)
  164. {
  165.     // Decrement the channel open counters
  166.  
  167.     switch (pChannel-> dwOpenType) {
  168.         case VIDEO_EXTERNALIN:
  169.             gwCaptureUsage--;
  170.             break;
  171.         case VIDEO_EXTERNALOUT:
  172.             gwDisplayUsage--;
  173.             break;
  174.         case VIDEO_IN:
  175. #ifdef USE_PROFILER
  176.             ProfFinish();
  177. #endif
  178.             // If started, or buffers in the queue,
  179.             // don't let the close happen
  180.             if (gfVideoInStarted || lpVHdrFirst)
  181.                 return DV_ERR_STILLPLAYING;
  182.  
  183.             gwVideoInUsage--;
  184.             break;
  185.         case VIDEO_OUT:
  186.             gwVideoOutUsage--;
  187.             break;
  188.         default:
  189.             break;
  190.     }
  191.  
  192.     gwDriverUsage--;  // Overall driver useage count
  193.  
  194.     if (gwDriverUsage == 0) {
  195.         HardwareFini ();        // Shut down the device
  196.         TransFini ();           // Free the translation table
  197.         FreeFrameBufferSelector ();  // Free the frame buffer selector 
  198.         fDeviceInitialized = FALSE;
  199.     }
  200.  
  201.     // Free the instance data
  202.     LocalFree((HLOCAL)pChannel);
  203.  
  204.     return DV_ERR_OK;
  205. }
  206.  
  207. /****************************************************************************
  208.   Show channel specific configuration dialogs
  209. ****************************************************************************/
  210. DWORD NEAR PASCAL VideoDialog (DWORD dwOpenType, HWND hWndParent, DWORD dwFlags)
  211. {
  212.     switch (dwOpenType) {
  213.         case VIDEO_EXTERNALIN:
  214.             if (dwFlags & VIDEO_DLG_QUERY)
  215.                 return DV_ERR_OK;       // Support the dialog
  216.             DialogBox(ghModule, MAKEINTRESOURCE(DLG_VIDEOSOURCE),
  217.                     (HWND)hWndParent, VideoSourceDlgProc);
  218.             break;
  219.  
  220.         case VIDEO_IN:
  221.             if (dwFlags & VIDEO_DLG_QUERY)
  222.                 return DV_ERR_OK;       // Support the dialog
  223.             DialogBox(ghModule, MAKEINTRESOURCE(DLG_VIDEOFORMAT),
  224.                     (HWND)hWndParent, VideoFormatDlgProc);
  225.             break;
  226.  
  227.         case VIDEO_OUT:
  228.             return DV_ERR_NOTSUPPORTED;
  229.  
  230.         case VIDEO_EXTERNALOUT:
  231.             if (dwFlags & VIDEO_DLG_QUERY)
  232.                 return DV_ERR_OK;       // Support the dialog
  233.             DialogBox(ghModule, MAKEINTRESOURCE (DLG_VIDEODISPLAY),
  234.                     (HWND)hWndParent, VideoMonitorDlgProc);
  235.             break;
  236.  
  237.         default:
  238.             return DV_ERR_NOTSUPPORTED;
  239.     }
  240.     return DV_ERR_OK;   // on either cancel or OK
  241. }
  242.  
  243. /****************************************************************************
  244.   Paint the key color
  245. ****************************************************************************/
  246. DWORD NEAR PASCAL VideoUpdate (PCHANNEL pChannel, HWND hWnd, HDC hDC)
  247. {
  248.    CT_Update (hWnd, hDC);
  249.    return DV_ERR_OK;
  250. }
  251.  
  252. /****************************************************************************
  253.   handles DVM_GET_CHANNEL_CAPS message
  254. ****************************************************************************/
  255. DWORD NEAR PASCAL VideoChannelCaps (PCHANNEL pChannel, LPCHANNEL_CAPS lpCaps, DWORD dwSize)
  256. {
  257.     lpCaps-> dwFlags = 0L;
  258.  
  259.     switch (pChannel->dwOpenType) {
  260.         case VIDEO_EXTERNALIN:
  261.             // For this device, scaling happens during digitization
  262.             // into the frame buffer.
  263.             lpCaps-> dwFlags = VCAPS_CAN_SCALE;
  264.             lpCaps-> dwSrcRectXMod = 1;         // Src undefined at present
  265.             lpCaps-> dwSrcRectYMod = 1;
  266.             lpCaps-> dwSrcRectWidthMod = 1;
  267.             lpCaps-> dwSrcRectHeightMod = 1;
  268.             lpCaps-> dwDstRectXMod = 4;
  269.             lpCaps-> dwDstRectYMod = 2;
  270.             lpCaps-> dwDstRectWidthMod = 40;
  271.             lpCaps-> dwDstRectHeightMod = 30;
  272.             break;
  273.  
  274.         case VIDEO_IN:
  275.             lpCaps-> dwFlags = 0;       // No scaling or clipping
  276.             lpCaps-> dwSrcRectXMod = 4;
  277.             lpCaps-> dwSrcRectYMod = 2;
  278.             lpCaps-> dwSrcRectWidthMod = 40;
  279.             lpCaps-> dwSrcRectHeightMod = 30;
  280.             lpCaps-> dwDstRectXMod = 4;
  281.             lpCaps-> dwDstRectYMod = 2;
  282.             lpCaps-> dwDstRectWidthMod = 40;
  283.             lpCaps-> dwDstRectHeightMod = 30;
  284.             break;
  285.  
  286.         case VIDEO_OUT:
  287.             return DV_ERR_NOTSUPPORTED;  
  288.             break;
  289.  
  290.         case VIDEO_EXTERNALOUT:
  291.             // Overlay cannot scale. Positions on 4 pix X, 2 pix Y boundaries
  292.             lpCaps-> dwFlags = VCAPS_OVERLAY;
  293.             lpCaps-> dwSrcRectXMod = 4;
  294.             lpCaps-> dwSrcRectYMod = 2;
  295.             lpCaps-> dwSrcRectWidthMod = 40;
  296.             lpCaps-> dwSrcRectHeightMod = 30;
  297.             lpCaps-> dwDstRectXMod = 4;
  298.             lpCaps-> dwDstRectYMod = 2;
  299.             lpCaps-> dwDstRectWidthMod = 40;
  300.             lpCaps-> dwDstRectHeightMod = 30;
  301.             break;
  302.  
  303.         default:
  304.             return DV_ERR_NOTSUPPORTED;
  305.     }
  306.     return DV_ERR_OK;
  307. }
  308.  
  309. /****************************************************************************
  310.   handles DVM_SRC_RECT and DVM_DST_RECT messages
  311. ****************************************************************************/
  312. DWORD NEAR PASCAL VideoRectangles (PCHANNEL pChannel, BOOL fSrc, LPRECT lpRect, DWORD dwFlags)
  313. {
  314.     static RECT rcMaxRect = {0, 0, 640, 480};
  315.  
  316.     if (lpRect == NULL)
  317.         return DV_ERR_PARAM1;
  318.  
  319.     // Note: many of the uses of the rectangle functions are not actually
  320.     // implemented by the sample driver, (or by Vidcap), but are included 
  321.     // here for future compatibility.
  322.  
  323.     switch (pChannel->dwOpenType) {
  324.         case VIDEO_EXTERNALIN:
  325.             if (!fSrc) {
  326.                 switch (dwFlags) {
  327.                    case VIDEO_CONFIGURE_SET:
  328.                    case VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT:
  329.                         // Where in the frame buffer should the incoming
  330.                         // video be digitized?
  331.                         // For this driver, we only digitize to 0,0
  332.  
  333.                         if ((lpRect->left == 0) && (lpRect->top == 0)) {
  334.                             // We should really do some setup here, but for
  335.                             // the moment, all dimensions are really controlled
  336.                             // by the DVM_SET_FORMAT message.
  337.                             grcDestExtIn = *lpRect;
  338.                             return DV_ERR_OK;
  339.                         }
  340.                         break;
  341.  
  342.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT:
  343.                         *lpRect = grcDestExtIn;
  344.                         return DV_ERR_OK;
  345.                    
  346.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_MAX:
  347.                         *lpRect = rcMaxRect;
  348.                         return DV_ERR_OK;
  349.  
  350.                    default:
  351.                         break;
  352.                 }
  353.             }
  354.             return DV_ERR_NOTSUPPORTED;  
  355.             break;
  356.  
  357.         case VIDEO_IN:
  358.             if (fSrc) {
  359.                 switch (dwFlags) {
  360.                    case VIDEO_CONFIGURE_SET:
  361.                    case VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT:
  362.                         // Where in the frame buffer should we take
  363.                         // the image from?
  364.                         if ((lpRect->right - lpRect->left == (int)gwWidth) &&
  365.                                 (lpRect->bottom - lpRect->top == (int)gwHeight)) {
  366.                             grcSourceIn = *lpRect;
  367.                             return DV_ERR_OK;
  368.                         }
  369.                         break;
  370.  
  371.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT:
  372.                         *lpRect = grcSourceIn;
  373.                         return DV_ERR_OK;
  374.                    
  375.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_MAX:
  376.                         *lpRect = rcMaxRect;
  377.                         return DV_ERR_OK;
  378.  
  379.                    default:
  380.                         break;
  381.                 }
  382.             }
  383.             return DV_ERR_NOTSUPPORTED;  
  384.             break;
  385.  
  386.         case VIDEO_OUT:
  387.             return DV_ERR_NOTSUPPORTED;  
  388.             break;
  389.  
  390.         case VIDEO_EXTERNALOUT:
  391.             if (fSrc) {
  392.                 if (dwFlags & VIDEO_CONFIGURE_SET) {
  393.                     // What part of the frame buffer should the 
  394.                     // overlay display ?
  395.                     // These are "Windows style" rects,
  396.                     // ie. 0,0 to 160,120 specifies a 160x120 rect.
  397.                     return SetExtOutSourceRect(lpRect);
  398.                 }
  399.                 else
  400.                     return DV_ERR_NOTSUPPORTED;  
  401.             }
  402.             else {
  403.                 if (dwFlags & VIDEO_CONFIGURE_SET) {
  404.                     // Screen coordinates where the overlay should
  405.                     // appear.  These are "Windows style" rects,
  406.                     // ie. 0,0 to 160,120 specifies a 160x120 rect.
  407.                     return SetExtOutDestRect(lpRect);
  408.                 }
  409.                 else
  410.                     return DV_ERR_NOTSUPPORTED;  
  411.             }
  412.  
  413.             break;
  414.  
  415.         default:
  416.             return DV_ERR_NOTSUPPORTED;
  417.     }
  418.     return DV_ERR_NOTSUPPORTED;
  419. }
  420.  
  421. /****************************************************************************
  422.   handles ConfigureStorage message
  423.         lParam1 is lpszKeyFile
  424.         lParam2 is dwFlags
  425. ****************************************************************************/
  426. DWORD NEAR PASCAL VideoConfigureStorageMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  427. {
  428.     if (lParam2 & VIDEO_CONFIGURE_GET)
  429.         CT_LoadConfiguration ((LPSTR) lParam1);
  430.     else if (lParam2 & VIDEO_CONFIGURE_SET)
  431.         CT_SaveConfiguration ((LPSTR) lParam1);
  432.     else
  433.         return DV_ERR_FLAGS;
  434.  
  435.     return DV_ERR_OK;
  436. }
  437.  
  438. /****************************************************************************
  439.  
  440.   handles Configure messages for video
  441.         lParam1 is dwFlags
  442.         lParam2 is LPVIDEOCONFIGPARMS
  443.  
  444. ****************************************************************************/
  445. DWORD NEAR PASCAL VideoConfigureMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  446. {
  447.     LPVIDEOCONFIGPARMS lpcp;
  448.     LPDWORD     lpdwReturn;    // Return parameter from configure.
  449.     LPVOID    lpData1;    // Pointer to data1.
  450.     DWORD    dwSize1;    // size of data buffer1.
  451.     LPVOID    lpData2;    // Pointer to data2.
  452.     DWORD    dwSize2;    // size of data buffer2.
  453.     DWORD       dwFlags;
  454.  
  455.     if (pChannel-> dwOpenType != VIDEO_IN)
  456.         return DV_ERR_NOTSUPPORTED;
  457.  
  458.     dwFlags = lParam1;
  459.  
  460.     lpcp = (LPVIDEOCONFIGPARMS) lParam2;
  461.     lpdwReturn = lpcp-> lpdwReturn;
  462.     lpData1 = lpcp-> lpData1;     
  463.     dwSize1 = lpcp-> dwSize1;     
  464.     lpData2 = lpcp-> lpData2;     
  465.     dwSize2 = lpcp-> dwSize2;     
  466.  
  467.     // Validate dwFlags
  468.     // FIX
  469.  
  470.     switch (msg) {
  471.  
  472.     case DVM_PALETTE:
  473.         switch (dwFlags) {
  474.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  475.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_GET):
  476.                 return DV_ERR_OK;
  477.  
  478.             case VIDEO_CONFIGURE_QUERYSIZE:
  479.             case (VIDEO_CONFIGURE_QUERYSIZE | VIDEO_CONFIGURE_GET):
  480.                *lpdwReturn = sizeof(LOGPALETTE) + 
  481.                     (palCurrent.palNumEntries-1) *
  482.                     sizeof(PALETTEENTRY);
  483.                break;
  484.  
  485.             case VIDEO_CONFIGURE_SET:
  486.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  487.                 if (!lpData1)       // points to a LOGPALETTE structure.
  488.                     return DV_ERR_PARAM1;
  489.                 return (SetDestPalette ( (LPLOGPALETTE) lpData1, 
  490.                         (LPBYTE) NULL));
  491.                 break;
  492.  
  493.             case VIDEO_CONFIGURE_GET:
  494.             case (VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT):
  495.                return (GetDestPalette ( (LPLOGPALETTE) lpData1, 
  496.                         (WORD) dwSize1));
  497.                break;
  498.  
  499.             default:
  500.                return DV_ERR_NOTSUPPORTED;
  501.         } // end of DVM_PALETTE switch
  502.  
  503.         return DV_ERR_OK;   
  504.  
  505.     case DVM_PALETTERGB555:  
  506.         switch (dwFlags) {
  507.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  508.                 return DV_ERR_OK;  // only set command is supported
  509.  
  510.             case VIDEO_CONFIGURE_SET:
  511.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  512.                 if (!lpData1)       // points to a LOGPALETTE structure.
  513.                     return DV_ERR_PARAM1;
  514.                 if (!lpData2)       // points to a 32k byte RGB555 translate table.
  515.                     return DV_ERR_PARAM2;
  516.                 if (dwSize2 != 0x8000)
  517.                     return DV_ERR_PARAM2;
  518.                 return (SetDestPalette ((LPLOGPALETTE)lpData1, 
  519.                         (LPBYTE) lpData2));
  520.                 break;
  521.  
  522.             default:
  523.                 return DV_ERR_NOTSUPPORTED;
  524.         } // end of SETPALETTERGB555 switch
  525.         return DV_ERR_OK;
  526.  
  527.     case DVM_FORMAT:
  528.         switch (dwFlags) {
  529.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  530.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_GET):
  531.                 return DV_ERR_OK;  // command is supported
  532.  
  533.             case VIDEO_CONFIGURE_QUERYSIZE:
  534.             case (VIDEO_CONFIGURE_QUERYSIZE | VIDEO_CONFIGURE_GET):
  535.                *lpdwReturn = sizeof(BITMAPINFOHEADER);
  536.                break;
  537.  
  538.             case VIDEO_CONFIGURE_SET:
  539.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  540.                 return (SetDestFormat ((LPBITMAPINFOHEADER) lpData1, 
  541.                         (WORD) dwSize1));
  542.                 break;
  543.  
  544.             case VIDEO_CONFIGURE_GET:
  545.             case (VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT):
  546.                 return (GetDestFormat ((LPBITMAPINFOHEADER) lpData1, 
  547.                         (WORD) dwSize1));
  548.                 break;
  549.  
  550.             default:
  551.                return DV_ERR_NOTSUPPORTED;
  552.         }  //end of DVM_FORMAT switch
  553.  
  554.         return DV_ERR_OK;
  555.  
  556.     default:        // Not a msg that we understand
  557.         return DV_ERR_NOTSUPPORTED;
  558.  
  559.     } // end of msg switch
  560.  
  561.     return DV_ERR_NOTSUPPORTED;
  562. }
  563.  
  564. /****************************************************************************
  565.  
  566.   handles Stream messages for video 
  567.  
  568. ****************************************************************************/
  569. DWORD NEAR PASCAL VideoStreamMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  570. {
  571.     DWORD       dwOpenType = pChannel-> dwOpenType;
  572.  
  573.  
  574.     if (dwOpenType == VIDEO_EXTERNALIN) {       // Capture channel
  575.         switch (msg) {
  576.             case DVM_STREAM_INIT:
  577.                 CT_Acquire (TRUE);
  578.                 break;
  579.             case DVM_STREAM_FINI:
  580.                 CT_Acquire (FALSE);
  581.                 break;
  582.             default:
  583.                 return DV_ERR_NOTSUPPORTED;
  584.         }
  585.         return DV_ERR_OK;
  586.     }
  587.  
  588.     else if (dwOpenType == VIDEO_EXTERNALOUT) { // Overlay channel
  589.         switch (msg) {
  590.             case DVM_STREAM_INIT:
  591.                 CT_OverlayEnable (TRUE);
  592.                 break;
  593.             case DVM_STREAM_FINI:
  594.                 CT_OverlayEnable (FALSE);
  595.                 break;
  596.             default:
  597.                 return DV_ERR_NOTSUPPORTED;
  598.         }
  599.         return DV_ERR_OK;
  600.     }
  601.  
  602.     else switch (msg) {                         // Input channel
  603.         //
  604.         //  lParam1     -   LPVIDEO_STREAM_INIT_PARMS
  605.         //
  606.         //  lParam2     -   sizeof (LPVIDEO_STREAM_INIT_PARMS)
  607.         //
  608.         case DVM_STREAM_INIT:           
  609.             return InStreamOpen((LPVIDEO_STREAM_INIT_PARMS)lParam1 );
  610.  
  611.         case DVM_STREAM_FINI:
  612.             return InStreamClose();
  613.  
  614.         case DVM_STREAM_GETERROR:
  615.             return InStreamError((LPDWORD) lParam1, (LPDWORD) lParam2);
  616.  
  617.         case DVM_STREAM_GETPOSITION:
  618.             return InStreamGetPos((LPMMTIME) lParam1, (DWORD) lParam2);
  619.  
  620.         case DVM_STREAM_ADDBUFFER:
  621.             return InStreamAddBuffer((LPVIDEOHDR)lParam1);
  622.  
  623.         case DVM_STREAM_PREPAREHEADER:  // Handled by MSVideo
  624.             return DV_ERR_NOTSUPPORTED;
  625.  
  626.         case DVM_STREAM_UNPREPAREHEADER: // Handled by MSVideo
  627.             return DV_ERR_NOTSUPPORTED;
  628.  
  629.         case DVM_STREAM_RESET:          
  630.             return InStreamReset();
  631.  
  632.         case DVM_STREAM_START:          
  633.             return InStreamStart();
  634.  
  635.         case DVM_STREAM_STOP:           
  636.             return InStreamStop();
  637.  
  638.         default:
  639.             return DV_ERR_NOTSUPPORTED;
  640.  
  641.     } // end switch on message type
  642. }
  643.  
  644. /****************************************************************************
  645.  
  646.   Main message handler
  647.  
  648. ****************************************************************************/
  649. DWORD NEAR PASCAL VideoProcessMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  650. {
  651.     DWORD       dwOpenType = pChannel-> dwOpenType;
  652.  
  653.     switch (msg) {
  654.         case DVM_GETERRORTEXT: /* lParam1 = LPVIDEO_GETERRORTEXT_PARMS */
  655.             if (LoadString(ghModule, 
  656.                     (WORD)  ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->dwError,
  657.                     (LPSTR) ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->lpText,
  658.                     (int)   ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->dwLength))
  659.                 return DV_ERR_OK;
  660.             else
  661.                 return DV_ERR_PARAM1;
  662.             break;            
  663.  
  664.         //
  665.         //  lParam1     -   hWndParent
  666.         //
  667.         //  lParam2     -   flags
  668.         //
  669.         case DVM_DIALOG: /* lParam1 = hWndParent, lParam2 = dwFlags */
  670.             return (VideoDialog (dwOpenType, (HWND) lParam1, (DWORD) lParam2));
  671.             break;
  672.  
  673.         case DVM_PALETTE:
  674.         case DVM_FORMAT:
  675.         case DVM_PALETTERGB555:
  676.             return VideoConfigureMessage(pChannel, msg, lParam1, lParam2);
  677.  
  678.         case DVM_SRC_RECT:
  679.         case DVM_DST_RECT:
  680.             return VideoRectangles (pChannel, (msg == DVM_SRC_RECT) /* fSource */,
  681.                         (LPRECT) lParam1, 
  682.                         (DWORD) lParam2);
  683.  
  684.         case DVM_UPDATE:
  685.             if (dwOpenType != VIDEO_EXTERNALOUT)
  686.                 return DV_ERR_NOTSUPPORTED;
  687.             return VideoUpdate (pChannel, (HWND) lParam1, (HDC) lParam2);
  688.  
  689.         case DVM_CONFIGURESTORAGE:
  690.             return VideoConfigureStorageMessage(pChannel, msg, lParam1, lParam2);
  691.  
  692.         case DVM_FRAME:
  693.             if (dwOpenType != VIDEO_IN)
  694.                 return DV_ERR_NOTSUPPORTED;
  695.  
  696.             return (CaptureFrame((LPVIDEOHDR)lParam1));
  697.  
  698.         case DVM_GET_CHANNEL_CAPS:
  699.             return VideoChannelCaps (pChannel, (LPCHANNEL_CAPS) lParam1,  (DWORD)lParam2); 
  700.  
  701.         default:
  702.             if (msg >= DVM_STREAM_MSG_START && msg <= DVM_STREAM_MSG_END)
  703.                 return VideoStreamMessage(pChannel, msg, 
  704.                         lParam1, lParam2);
  705.             else
  706.                 return DV_ERR_NOTSUPPORTED;
  707.     }
  708. }
  709.  
  710.